﻿#include "common.h" // 包含预编译头文件
#include "MyWindow.h"

MyWindow::MyWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MyWindowClass())
    , coord_window(new CoordWindow(this))
    , my_coord_thread(nullptr)
    //, try_error(false)
    , input_file("")
    , audio_tempo(1.0f)
    , my_player(nullptr)
    //, volume_control(nullptr)
    , file_duration(-1)
    , slider_is_pressed(false) // Initialize slider_is_pressed
    //, timerCoord(new QTimer(this))
    , timerLeft(new QTimer(this))
    , timerRight(new QTimer(this))
    , audio_transcoder(nullptr)
    , open_pcm_window(nullptr)
    //, transcoder_thread(nullptr)
    , recording_window(nullptr)
    //, recording_thread(nullptr)
{
    ui->setupUi(this);

    /*
    // 确保所有 QSlider 可用并可获得焦点
    ui->horizontalSlider->setEnabled(true);
    ui->horizontalSlider->setFocusPolicy(Qt::StrongFocus);

    ui->verticalSliderPitch->setEnabled(true);
    ui->verticalSliderPitch->setFocusPolicy(Qt::StrongFocus);

    ui->verticalSliderRate->setEnabled(true);
    ui->verticalSliderRate->setFocusPolicy(Qt::StrongFocus);

    ui->horizontalSlider_listenerX->setEnabled(true);
    ui->horizontalSlider_listenerX->setFocusPolicy(Qt::StrongFocus);

    ui->horizontalSlider_listenerY->setEnabled(true);
    ui->horizontalSlider_listenerY->setFocusPolicy(Qt::StrongFocus);

    ui->horizontalSlider_listenerZ->setEnabled(true);
    ui->horizontalSlider_listenerZ->setFocusPolicy(Qt::StrongFocus);
    */

    //connect(ui->widgetMain, &QWidget::, this, &MusicPlayer::stop);

    // 音量控制相关
    //volume_control = new VolumeControl(this);

    // 设置声音效果相关操作不可用
    ui->checkBox_density->setEnabled(false);
    ui->checkBox_diffusion->setEnabled(false);
    ui->checkBox_gain->setEnabled(false);
    ui->checkBox_decay_time->setEnabled(false);
    ui->checkBox_gainhf->setEnabled(false);
    ui->checkBox_decay_hfratio->setEnabled(false);
    ui->checkBox_reflections_gain->setEnabled(false);
    ui->checkBox_reflections_delay->setEnabled(false);
    ui->checkBox_late_reverb_gain->setEnabled(false);
    ui->dial_density->setEnabled(false);
    ui->doubleSpinBoxDensity->setEnabled(false);
    ui->dial_diffusion->setEnabled(false);
    ui->doubleSpinBoxDiffusion->setEnabled(false);
    ui->dial_gain->setEnabled(false);
    ui->doubleSpinBoxGain->setEnabled(false);
    ui->dial_gainhf->setEnabled(false);
    ui->doubleSpinBoxGainHF->setEnabled(false);
    ui->dial_decay_time->setEnabled(false);
    ui->doubleSpinBoxDecayTime->setEnabled(false);
    ui->dial_decay_hfratio->setEnabled(false);
    ui->doubleSpinBoxDecayHFRatio->setEnabled(false);
    ui->dial_reflections_gain->setEnabled(false);
    ui->doubleSpinBoxReflectionsGain->setEnabled(false);
    ui->dial_reflections_delay->setEnabled(false);
    ui->doubleSpinBoxReflectionsDelay->setEnabled(false);
    ui->dial_late_reverb_gain->setEnabled(false);
    ui->doubleSpinBoxLateReverbGain->setEnabled(false);

    // 安装事件过滤器，使三个监听器 Slider 支持鼠标滚轮
    ui->horizontalSlider_listenerX->installEventFilter(this);
    ui->horizontalSlider_listenerY->installEventFilter(this);
    ui->horizontalSlider_listenerZ->installEventFilter(this);

    // 构造函数中添加
    ui->pushButtonVolume->installEventFilter(this);
    ui->pushButtonSpeed->installEventFilter(this);

    // 安装事件过滤器用于显示悬停/拖动值
    ui->verticalSlider_f62->installEventFilter(this);

    // 替换原有 QSlider 控件为 CustomSlider
    //ui->verticalSlider_f62 = new CustomSlider(this);
    //ui->verticalSlider_f125 = new CustomSlider(this);
    //ui->verticalSlider_f250 = new CustomSlider(this);
    //ui->verticalSlider_f500 = new CustomSlider(this);
    //ui->verticalSlider_f1000 = new CustomSlider(this);
    //ui->verticalSlider_f2000 = new CustomSlider(this);
    //ui->verticalSlider_f4000 = new CustomSlider(this);
    //ui->verticalSlider_f8000 = new CustomSlider(this);
    //ui->verticalSlider_f16000 = new CustomSlider(this);

    // 音频转码窗口
    connect(ui->actionTranscode, &QAction::triggered,
        [this]() {
            if (audio_transcoder && !audio_transcoder->isClosed()) {
                audio_transcoder->show();
            }

            /*if (transcoder_thread) {
                transcoder_thread->quit();
                transcoder_thread->wait();
                delete transcoder_thread;
                transcoder_thread = nullptr;
            }*/
            if (audio_transcoder) {
                audio_transcoder->deleteLater();
                //delete audio_transcoder;
                audio_transcoder = nullptr;
            }
            audio_transcoder = new TranscodeWindow();
            audio_transcoder->show();
            connect(audio_transcoder, &TranscodeWindow::showMainWindowSignal,
                [this]() {
                    this->setEnabled(true); // 启用主窗口
                });
        });
    /*connect(audio_transcoder, &TranscodeWindow::destroyed,
        [this]() {
            if (audio_transcoder)
                delete audio_transcoder;
            qDebug() << "transcode window closed";
        });
    connect(audio_transcoder, &TranscodeWindow::closeSignal,
        [this]() {
            if (audio_transcoder)
                delete audio_transcoder;
            qDebug() << "transcode window closed";
        });*/

    // 重置设置
    //connect(ui->pushButton_reset, &QPushButton::clicked, this, &MyWindow::resetSlot);

    initConnectSlots();

    setInitStyle();
}

MyWindow::~MyWindow()
{
    if (my_player) {
        delete my_player;
        my_player = nullptr;
    }
    if (my_coord_thread) {
        delete coord_window;
        coord_window = nullptr;
    }
    if (audio_transcoder) {
        delete audio_transcoder;
        audio_transcoder = nullptr;
    }
    if (open_pcm_window) {
        delete open_pcm_window;
        open_pcm_window = nullptr;
    }
    if (recording_window) {
        delete recording_window;
        recording_window = nullptr;
    }
    delete ui;
}

void MyWindow::openFileSlot(bool try_error)
{
    QString fileName;
    if (try_error && !input_file.empty()) {
        fileName = QString::fromStdString(input_file);
        return;
    }

    fileName = QFileDialog::getOpenFileName(this, tr("Open Music File"), "", tr("Audio Files (*.mp2 *.mp3 *.wav *.flac *.aac *.m4a *.pcm *.ogg *.ape *.wsaud *.wma *.rka *.wve)"));

    if (!fileName.endsWith(".pcm"))
        if (fileName == input_file || fileName.isEmpty())
            return;

    if (fileName.endsWith(".pcm")) {
        if (open_pcm_window) {
            //open_pcm_window->close();
            delete open_pcm_window;
            open_pcm_window = nullptr;
        }
        open_pcm_window = new OpenPCMWindow(this);
        open_pcm_window->show();

        connect(open_pcm_window, &OpenPCMWindow::finished, this,
            [this, fileName](bool sure, QString setting) {
                if (sure) {
                    qDebug() << "Open PCM file: " << fileName << " with setting: " << setting;

                    // 这里可以放置其他需要在窗口关闭后执行的代码
                    openPlayer(fileName.toUtf8().constData(), true);
                }
                else {
                    qDebug() << "Open PCM file canceled";
                }
                this->setEnabled(true); // 启用主窗口
            });
        this->setEnabled(false); // 禁用主窗口
        open_pcm_window->setEnabled(true);
    }
    else {
        is_pcm_format_set_successfully = true;
        openPlayer(fileName.toUtf8().constData()); // const 引用
    }
}

void MyWindow::openPlayer(const std::string& fileName, bool is_pcm)
{
    // 先释放之前的资源
    if (my_player) {
        if (my_player->is_playing)
            my_player->pause();
        delete my_player;
        my_player = nullptr; // 置空指针，防止后面使用
    }

    //qDebug() << "Open file QString: " << fileName;
    input_file = fileName;
    //QDir dir(QFileInfo(fileName).absolutePath()); // 获取文件所在目录
    //qDebug() << "Open file c_str: " << input_file.c_str();
    //qDebug() << "retry Open file c_str: " << fileName.toStdString().c_str();

    int position = 0;
    if (is_pcm) {
        // 这里设置 PCM 文件的起始位置
        position = ui->horizontalSlider->value();
    }

    my_player = new MusicPlayer(input_file);
    if (!my_player) {
        qDebug() << "fail to create player";
        ui->statusBar->showMessage("create player object failed");
        delete my_player;
        return;
    }
    if (open_file_error || !my_player->my_ffmpeg) {
        qDebug() << "Open file error: " << open_file_error;
        char error_msg[256];
        av_strerror(open_file_error, error_msg, sizeof(error_msg));
        ui->statusBar->showMessage(QString("Open file error: ") + error_msg);
        delete my_player;
        my_player = nullptr; // 置空指针，防止后面使用
        return;
    }

    // 判断 PCM 文件打开是否成功
    if (!is_pcm_format_set_successfully) {
        delete my_player;
        my_player = nullptr; // 置空指针，防止后面使用
        ui->statusBar->showMessage("Open PCM file failed");
        QMessageBox::warning(this, "Open PCM File Error", "打开 PCM 文件失败。可能是 PCM 文件格式设置的问题，请检查，需要重新打开文件");
    }

    if (!my_player)
        return;

    // 启动监听器坐标线程
    if (my_coord_thread) {
        delete my_coord_thread;
        my_coord_thread = nullptr;
        if (!input_file.empty())
            ui->statusBar->showMessage(("Open file>> " + input_file + " failed").c_str());
    }
    my_coord_thread = new ListenerCoordThread(this, coord_window, my_player);
    if (!my_coord_thread) {
        qDebug() << "fail to create coord thread";
        return;
    }

    ui->statusBar->showMessage(("Open file>> " + input_file).c_str());

    // 设置声音效果
    setAllCurrentReverbEffects();

    connect(ui->pushButton_play, &QPushButton::clicked, this, &MyWindow::playSlot);
    //connect(ui->actionResave, &QAction::triggered, this, &MyWindow::recordingSlot);
    connect(ui->pushButton_pause, &QPushButton::clicked, this, &MyWindow::pauseSlot);

    file_duration = my_player->get_reader_duration(); // 保存浮点数
    ui->horizontalSlider->setRange(0, file_duration * 1000 - 8); // 设置进度条范围毫秒级
    // 显示总时长，格式化显示传入的是毫秒数
    ui->labelDuration->setText(QTime(0, 0, 0, 0).addMSecs(file_duration * 1000).toString("hhh:mm:ss:zz"));

    // 进度条拖动相关，增加标志位
    connect(ui->horizontalSlider, &QSlider::sliderPressed,
        [this]() -> void {
            slider_is_pressed = true;
            seekingSlot();
        });
    connect(ui->horizontalSlider, &QSlider::sliderReleased,
        [this]() -> void {
            slider_is_pressed = false;
            seekToSlot();
        });
    connect(ui->horizontalSlider, &QSlider::sliderMoved, this, &MyWindow::seekingSlot);

    // 强制使用QueuedConnection，确保跨线程信号槽
    connect(my_player, &MusicPlayer::audio_frame_read, this, &MyWindow::setAudioPositionSlot, Qt::QueuedConnection);
    connect(my_player, &MusicPlayer::audio_end, this, &MyWindow::audioEndSlot, Qt::QueuedConnection);

    // 设置打开文件相关槽函数
    initOpenFileConnectSlot();
    my_player->seek_to_position(position * 1000); // 跳转到指定位置
}


//QString MyWindow::formatTime(double seconds)
//{ // QTime 已经封装好了
//    int hours = seconds / 3600; // 取整
//    seconds -= hours * 3600.0;
//    int minutes = seconds / 60.0;
//    seconds -= minutes * 60.0;  // 取整
//
//    return QString("%1:%2:%3").arg(hours, 2, 10, QChar('0')).arg(minutes, 2, 10, QChar('0')).arg(seconds, 2, 'f', 2, QChar('0'));
//}

void MyWindow::initConnectSlots()
{
    // 打开文件
    connect(ui->actionOpen, &QAction::triggered, this, &MyWindow::openFileSlot);

    // 打开 pcm 文件时，发生错误时弹出错误提示框
    //connect(my_player->my_ffmpeg, &MusicReader::open_pcm_file_error, this,
    //    [this]() {
    //        QMessageBox::warning(this, "Open PCM File Error", "Failed to open PCM file.");
    //        delete my_player;
    //        my_player = nullptr; // 置空指针，防止后面使用
    //        ui->statusBar->showMessage("Open PCM filed");
    //    });

    // 添加 centralWidget 右键菜单支持
    ui->centralWidget->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(ui->centralWidget, &QGroupBox::customContextMenuRequested, this, &MyWindow::onCentralWidgetContextMenuRequested);

    // 确保窗口部件可以获得焦点
    setFocusPolicy(Qt::StrongFocus);
    timerLeft->setInterval(300); // 300ms 刷新一次
    connect(timerLeft, &QTimer::timeout, this, &MyWindow::keyLeftHoldSlot);
    timerRight->setInterval(300); // 300ms 刷新一次
    connect(timerRight, &QTimer::timeout, this, &MyWindow::keyRightHoldSlot);

    // 速度与音量相关
    sliderSpeed = new QSlider(Qt::Horizontal, this);
    sliderSpeed->setRange(50, 500); // 0.5x ~ 5.0x
    sliderSpeed->setValue(100);
    sliderSpeed->setFixedWidth(150);
    labelSpeed = new QLabel(QString(u8"速度: %1x").arg(sliderSpeed->value() / 100.0f, 0, 'f', 2), this);
    connect(sliderSpeed, &QSlider::valueChanged,
        [this](int value) {
            float speed = value / 100.0f;
            if (labelSpeed)
                labelSpeed->setText(QString(u8"速度: %1x").arg(speed, 0, 'f', 2));
            if (my_player)
                my_player->set_audio_tempo(speed);
        });
    sliderSpeed->installEventFilter(this);
    labelSpeed->installEventFilter(this);
    //sliderSpeed->setStyleSheet("background-color: lightpink; border-radius: 10px;");
    sliderSpeed->setStyleSheet("QSlider { background-color: lightpink; border-radius: 10px; }"
        "QSlider::groove:horizontal { height: 8px; background-color: lightblue; }"
        "QSlider::handle:horizontal { width: 15px; margin: -5px 0; border-radius: 7px; background-color: lightgreen; }"
        "QSlider::add-page:horizontal { background: lightblue; }"); // 设置整个滑块控件的背景颜色)

    labelSpeed->setStyleSheet("background-color: transparent; color: pink; font-size: 12px; font-weight: bold;"); // 设置背景色为透明
    sliderSpeed->hide();
    labelSpeed->hide();

    sliderVolume = new QSlider(Qt::Vertical, this);
    sliderVolume->setRange(0, 200);
    sliderVolume->setValue(100); // 可根据实际音量设置
    sliderVolume->setFixedWidth(ui->pushButtonVolume->width());
    sliderVolume->setFixedHeight(150);
    labelVolume = new QLabel(QString(u8"%1%").arg(sliderVolume->value()), this);
    // 获取按钮的位置和大小
    QRect buttonRect = ui->pushButtonVolume->geometry();
    connect(sliderVolume, &QSlider::valueChanged,
        [this](int value) {
            // 这里设置音量
            if (labelVolume)
                labelVolume->setText(QString(u8"%1%").arg(value));
            if (my_player)
                my_player->set_volume(value);
        });
    sliderVolume->installEventFilter(this);
    labelVolume->installEventFilter(this);
    labelVolume->setAlignment(Qt::AlignCenter);
    labelVolume->setFixedWidth(ui->pushButtonVolume->width());
    labelVolume->setFixedHeight(15);
    sliderVolume->setStyleSheet("QSlider { background-color: #fff; border-radius: 10px; }"
        "QSlider::groove:vertical { width: 8px; background: lightblue; }"
        "QSlider::handle:vertical { height: 20px; margin: 0 -6px; border-radius: 10px; background-color: lightpink; }"); // 设置背景色为浅黄色
    labelVolume->setStyleSheet("background-color: transparent; color: pink; font-size: 12px; font-weight: bold;"); // 设置背景色为浅黄色
    sliderVolume->hide();
    labelVolume->hide();

    // 录音功能
    connect(ui->actionRecording, &QAction::triggered, this, &MyWindow::recordingSlot);
}

